from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible
from fdfs_client.client import Fdfs_client
from django.conf import settings


@deconstructible
class FDFSStorage(Storage):
    '''FDFS文件存储类'''

    def __init__(self, client_conf=None, base_url=None):
        '''django在创建对象时候需要支持不传参数创建对象,所以要给参数设置默认值'''

        if client_conf is None:
            client_conf = settings.DEFAULT_FILE_STORAGE
        self.client_conf = client_conf

        if base_url is None:
            base_url = settings.FDFS_NGINX_URL
        self.base_url = base_url

    def _save(self, name, content):

        '''
        :param name: 上传文件的名称
        :param content: 包含上传文件内容的file对象,可以通过content.read(),获取上传文件的内容
        :return:
        '''

        # 创建文件上传
        client = Fdfs_client(settings.FDFS_CLIENT_CONF)

        res = client.upload_by_buffer(content.read())

        if res.get('Status') != 'Upload successed.':
            raise Exception('文件上传失败')

        file_id = res.get('Remote file_id')
        return file_id

    def exists(self, name):
        '''django在调用_save方法之前,会先调用exists方法,
        来判断文件名是否跟系统中原有的文件名有冲突.
        因为fdfs中的文件名是自动生成的,所以不会冲突直接返回False
        name:上传文件的名字
        '''
        return False

    def url(self, name):
        '''返回完整的url地址
        name:数据库中保存的文件的file_id,也就是表中存储的image字段的内容
        '''
        return self.base_url + name
